package com.ruoyi.common.utils.modbus;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.math.BigInteger;
import java.net.Socket;

/**
 * 类描述：向指定IP端口发送数据
 *
 * @author lsw
 * @date 2024-02-23 09:21
 **/
public class SocketUtils {
    private static final Logger LOGGER = LoggerFactory.getLogger(SocketUtils.class);
    private static Socket socket = null;
    private static final String archivesCenterAPIIP = "127.0.0.1";
    private static final String archivesCenterAPIPort = "8090";

    public static boolean connection() {
        if (socket != null) {
            return true;
        }

        try {
            socket = new Socket(archivesCenterAPIIP, NumberUtils.toInt(archivesCenterAPIPort));
            return true;
        } catch (Exception e) {
            LOGGER.error("connection error", e);
            return false;
        }
    }

    public static void stop() {
        try {
            if (socket != null) {
                socket.close();
                socket = null;
            }
        } catch (Exception e) {
            LOGGER.error("connection error", e);
        }
    }

    /**
     * 发送数据
     *
     * @param cmd 需要发送的数据(十六进制的字符串形式)
     * @return 接受到的数据(十六进制的字符串形式)
     */
    public static String sendCmd(String cmd) {
        if (!connection() || socket == null) {
            return "error";
        }

        try {
            OutputStream out = socket.getOutputStream();
            byte[] hexStrToByteArrs = hexStrToByteArrs(cmd);
            if (hexStrToByteArrs == null) {
                return "error";
            }
//            out.write(hexStrToByteArrs);

            //3. 通过输出流，写入数据到 数据通道, 使用字符流
            BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(out));
            bufferedWriter.write(cmd);
            bufferedWriter.newLine();//插入一个换行符，表示写入的内容结束, 注意，要求对方使用readLine()!!!!
            bufferedWriter.flush();// 如果使用的字符流，需要手动刷新，否则数据不会写入数据通道


            InputStream in = socket.getInputStream();
            byte[] buf = new byte[1024];
            int len = in.read(buf);

            stop();

            return bytesToHexString(buf);
        } catch (IOException e) {
            LOGGER.error("sendCmd error", e);
            return "error";
        }
    }

    /**
     * 将十六进制的字符串转换成字节数组
     *
     * @param hexString 十六进制的字符串
     * @return byte[]
     */
    public static byte[] hexStrToByteArrs(String hexString) {
        if (StringUtils.isEmpty(hexString)) {
            return null;
        }

        hexString = hexString.replaceAll(" ", "");
        int len = hexString.length();
        int index = 0;

        byte[] bytes = new byte[len / 2];

        while (index < len) {
            String sub = hexString.substring(index, index + 2);
            bytes[index / 2] = (byte) Integer.parseInt(sub, 16);
            index += 2;
        }

        return bytes;
    }

    /**
     * 数组转换成十六进制字符串
     *
     * @param bArray 数组
     * @return HexString
     */
    public static String bytesToHexString(byte[] bArray) {
        StringBuilder sb = new StringBuilder(bArray.length);
        String sTemp;
        for (byte b : bArray) {
            sTemp = Integer.toHexString(0xFF & b);
            if (sTemp.length() < 2)
                sb.append(0);
            sb.append(sTemp.toUpperCase());
            // 在这里故意追加一个逗号便于最后的区分
            sb.append(" ");
        }
        return sb.toString();
    }


    /*
     * 将16进制数字解码成字符串,适用于所有字符（包括中文）
     */
    public static String decode(String bytes) {
        String hexString = "0123456789ABCDEF";
        ByteArrayOutputStream base = new ByteArrayOutputStream(bytes.length() / 2);
        // 将每2位16进制整数组装成一个字节
        for (int i = 0; i < bytes.length(); i += 2)
            base.write((hexString.indexOf(bytes.charAt(i)) << 4 | hexString
                    .indexOf(bytes.charAt(i + 1))));
        return base.toString();
    }


    /**
     * 16进制数转换为浮点数值
     *
     * @param str 16进制数据 424802C8= 50.002716
     */
    public static Float intBitsToFloat(String str) {
        BigInteger b = new BigInteger(str, 16);
        return Float.intBitsToFloat(b.intValue());
    }

    public static void main(String[] args) throws UnsupportedEncodingException {
        //34.6°
        String str = sendCmd("00 00 00 00 00 06 01 03 00 04 00 02");
//        String str="00 00 00 00 00 06 01 03 00 02 00 02";
        String x = str.replaceAll("\\s*", "");
        String s = str.split(" ")[8];
        String substring = x.substring(18, Integer.parseInt(s) * 2 + 18);
        System.out.println(substring);
//        System.out.println(intBitsToFloat(substring));
    }


}


